package com.orientation.service.impl;

import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.orientation.commom.exception.CustomException;
import com.orientation.dto.ReserveGoodsDto;
import com.orientation.entity.Goods;
import com.orientation.entity.Receive;
import com.orientation.entity.Student;
import com.orientation.mapper.GoodsMapper;
import com.orientation.mapper.ReceiveMapper;
import com.orientation.service.GoodsService;
import com.orientation.service.ReceiveService;
import com.orientation.service.StudentService;
import com.orientation.utils.BeanConvertUtils;
import com.orientation.utils.PageUtils;
import com.orientation.vo.ReceiveGoodsStudentVo;
import com.orientation.vo.StudentClassInfoVo;
import com.orientation.vo.StudentProgressVo;
import com.sun.istack.internal.NotNull;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.toList;

/**
 * <p>
 * 物质领取状态表 服务实现类
 * </p>
 *
 * @author xuandian
 * @since 2022-01-09
 */
@Service
public class ReceiveServiceImpl extends ServiceImpl<ReceiveMapper, Receive> implements ReceiveService {
    @Resource
    private StudentService studentService;
    @Resource
    private GoodsMapper goodsMapper;
    @Resource
    private GoodsService goodsService;
    @Resource
    private FilesService filesService;

    @Override
    public void insertReceive(ReserveGoodsDto reserveGoodsDto) {
        if (!CollectionUtils.isEmpty(reserveGoodsDto.getIdList()) && StringUtils.hasLength(reserveGoodsDto.getStudentId())) {
            Student studentServiceOne = studentService.getOne(Wrappers.<Student>lambdaQuery().eq(Student::getStudentId, reserveGoodsDto.getStudentId()));
            if (studentServiceOne == null) {
                throw new CustomException("18", "无该学生信息,请先维护学生信息");
            }
            List<Receive> list = this.list(Wrappers.<Receive>lambdaQuery().eq(Receive::getStudentId, reserveGoodsDto.getStudentId()).in(!CollectionUtils.isEmpty(reserveGoodsDto.getIdList()), Receive::getGoodsId, reserveGoodsDto.getIdList()));
            if (!CollectionUtils.isEmpty(list)) {
                throw new CustomException("18", "存在重复物品信息添加" + list.toString());
            }
            // log.error("reserveGoodsDto:{}", reserveGoodsDto);
            List<Receive> receiveList = new ArrayList<>();
            for (int i = 0; i < reserveGoodsDto.getIdList().size(); i++) {
                Receive receive = new Receive();
                receive.setGoodsId(reserveGoodsDto.getIdList().get(i));
                receive.setReceiveStatus(0);
                receive.setStudentId(reserveGoodsDto.getStudentId());
                receiveList.add(receive);
            }
            if (!CollectionUtils.isEmpty(receiveList)) {
                saveBatch(receiveList);
            }
        }
    }

    @Override
    public IPage<ReceiveGoodsStudentVo> queryReceiveGoodsStudentVo(Integer pageNum, Integer pageSize, Integer receiveStatus, String collegeId, String majorId, String className, String studentName, String studentId) {
        List<StudentClassInfoVo> studentClassInfoVos = studentService.getStudentClassInfoVos(collegeId, majorId, className, studentName, null, "1", studentId);
        List<Receive> receives = new ArrayList<>();
        List<ReceiveGoodsStudentVo> receiveGoodsStudentVos = getReceiveGoodsStudentVos(receiveStatus, studentClassInfoVos);
        return PageUtils.getPage(receiveGoodsStudentVos, pageNum, pageSize);
    }

    @NotNull
    private List<ReceiveGoodsStudentVo> getReceiveGoodsStudentVos(Integer receiveStatus, List<StudentClassInfoVo> studentClassInfoVos) {
        List<Receive> receives = new ArrayList<>();
        if (!CollectionUtils.isEmpty(studentClassInfoVos)) {
            List<String> studentIds = studentClassInfoVos.stream().map(StudentClassInfoVo::getStudentId).distinct().collect(Collectors.toList());
            receives = this.list(Wrappers.<Receive>lambdaQuery().eq(StringUtils.hasLength(receiveStatus == null ? null : receiveStatus.toString()), Receive::getReceiveStatus, receiveStatus)
                    .in(!CollectionUtils.isEmpty(studentIds), Receive::getStudentId, studentIds));
        } else {
            throw new CustomException("18", "暂无数据");
        }
        List<ReceiveGoodsStudentVo> receiveGoodsStudentVos = new ArrayList<>();
        if (!CollectionUtils.isEmpty(receives)) {
            List<String> GoodsIds = receives.stream().map(Receive::getGoodsId).distinct().collect(Collectors.toList());
            List<Goods> goodsList = goodsMapper.selectList(new LambdaQueryWrapper<Goods>().in(Goods::getSid, GoodsIds));
            if (!CollectionUtils.isEmpty(goodsList)) {
                if (!CollectionUtils.isEmpty(studentClassInfoVos)) {
                    receiveGoodsStudentVos = BeanConvertUtils.copyListProperties(receives, ReceiveGoodsStudentVo::new);
                    //交集
                    List<Receive> finalReceives = receives;
                    List<StudentClassInfoVo> classInfoVos = studentClassInfoVos.stream().filter(r -> finalReceives.stream().map(Receive::getStudentId).collect(toList()).contains(r.getStudentId())).collect(toList());
                    //   List<ReceiveGoodsStudentVo> collect = receiveGoodsStudentVos.stream().filter(r -> !receives.stream().map(Receive::getStudentId).collect(toList()).contains(r.getStudentId())).collect(toList());
                    for (ReceiveGoodsStudentVo vo : receiveGoodsStudentVos) {
                        for (StudentClassInfoVo receiveGo : classInfoVos) {
                            if (receiveGo.getStudentId().equals(vo.getStudentId())) {
                                vo.setCollegeName(receiveGo.getCollegeName());
                                vo.setClassName(receiveGo.getClassName());
                                vo.setStudentName(receiveGo.getStudentName());
                                vo.setMajorName(receiveGo.getMajorName());
                            }
                        }
                        for (Goods goods : goodsList) {
                            if (goods.getSid().equals(vo.getGoodsId())) {
                                vo.setGoodsName(goods.getGoodsName());
                                vo.setGoodsType(goods.getGoodsType());
                                vo.setGoodsUrl(goods.getGoodsUrl());
                            }
                        }
                    }
                }
            }
        }
        //根据学生id 排序
        receiveGoodsStudentVos = receiveGoodsStudentVos.stream().sorted(Comparator.comparing(ReceiveGoodsStudentVo::getStudentId)).collect(Collectors.toList());
        return receiveGoodsStudentVos;
    }

    @Override
    public void updateOrinsertReceive(MultipartFile[] files, String sid, List<String> urls) {
        Receive receive = new Receive();
        String FilesUrl = "";
        if (CollectionUtils.isEmpty(urls)) {
            receive.setFilesUrl(null);
        } else {
            List<String> strings = urls.stream().distinct().collect(toList());
            StringBuffer stringBuffer = new StringBuffer();
            for (String s : strings) {
                stringBuffer.append(s);
                stringBuffer.append(",");
            }
            FilesUrl = stringBuffer.toString().substring(0, stringBuffer.length() - 1);
        }
        if (files != null && files.length > 0) {
            List<String> stringUrls = filesService.getStringUrls(files);
            if (!CollectionUtils.isEmpty(stringUrls)) {
                receive.setFilesUrl(stringUrls == null ? null : org.apache.commons.lang3.StringUtils.join(stringUrls, ","));
            }
        }
        if (StringUtils.hasLength(FilesUrl) && StringUtils.hasLength(receive.getFilesUrl())) {
            receive.setFilesUrl(FilesUrl + "," + receive.getFilesUrl());
        }
        if (StringUtils.hasLength(FilesUrl) && !StringUtils.hasLength(receive.getFilesUrl())) {
            receive.setFilesUrl(FilesUrl);
        }
        receive.setReceiveStatus(1);
        receive.setSid(sid);
        updateById(receive);
    }

    @Override
    public void statisticsExport(Integer receiveStatus, String majorId, String className, String studentName, String studentId, HttpServletResponse response) {
        List<StudentClassInfoVo> studentClassInfoVos = studentService.getStudentClassInfoVos(null, majorId, className, studentName, null, "1", studentId);
        List<ReceiveGoodsStudentVo> receiveGoodsStudentVos = getReceiveGoodsStudentVos(receiveStatus, studentClassInfoVos);
        if (!CollectionUtils.isEmpty(receiveGoodsStudentVos)) {
            ExcelWriter writer = ExcelUtil.getWriter(true);
            writer.addHeaderAlias("studentId", "学号");
            writer.addHeaderAlias("studentName", "姓名");
            writer.addHeaderAlias("goodsName", "物品名");
            writer.addHeaderAlias("collegeName", "学院名称");
            writer.addHeaderAlias("majorName", "专业名称");
            writer.addHeaderAlias("className", "班级名称");
            writer.addHeaderAlias("receiveStatus", "领取状态0待领取1已经领走");
            writer.addHeaderAlias("goodsType", "物品类型");
            writer.setOnlyAlias(true);
            writer.write(receiveGoodsStudentVos, true);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=receiveStatisticsExport.xlsx");
            ServletOutputStream out = null;
            try {
                out = response.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        } else {
            throw new CustomException("18", "该条件下没有学生数据");
        }
    }

    @Override
    public void insertReceiveOne(String goodsId, String studentId) {
        if (StringUtils.hasLength(goodsId) && StringUtils.hasLength(studentId)) {
            Receive receiveOne = this.getOne(Wrappers.<Receive>lambdaQuery().eq(Receive::getStudentId, studentId).eq(StringUtils.hasLength(goodsId), Receive::getGoodsId, goodsId));
            if (!ObjectUtils.isEmpty(receiveOne)) {
                throw new CustomException("18", "存在重复物品信息添加");
            }
            Receive receive = new Receive();
            receive.setGoodsId(goodsId);
            receive.setStudentId(studentId);
            receive.setReceiveStatus(0);
            this.save(receive);
        } else {
            throw new CustomException("18", "重复物品信息必填");
        }


    }

    @Override
    public StudentProgressVo progressReceive(String collegeId) {
        StudentProgressVo studentProgressVo = new StudentProgressVo();
        // List<Student> students = studentService.list(Wrappers.<Student>lambdaQuery().isNotNull(Student::getStudentId));
        List<Student> students = studentService.list(Wrappers.<Student>lambdaQuery().eq(StringUtils.hasLength(collegeId), Student::getCollegeId, collegeId));
        List<Student> studentList = students.stream().filter((Student s) -> StringUtils.hasLength(s.getStudentId())).collect(Collectors.toList());
        List<Goods> goodsList = goodsService.list();
        int count = 0;
        if (!CollectionUtils.isEmpty(goodsList) && !CollectionUtils.isEmpty(students) && !CollectionUtils.isEmpty(studentList)) {
            for (Student student : studentList) {
                List<Receive> receiveList = this.list(Wrappers.<Receive>lambdaQuery().eq(Receive::getStudentId, student.getStudentId()));
                if (receiveList.size() == goodsList.size()) {
                    count++;
                }
            }
            studentProgressVo.setNotNum(students.size() - count);
            studentProgressVo.setReserveNum(count);
            studentProgressVo.setStudentNum(students.size());
            BigDecimal installRate = new BigDecimal(count).multiply(new BigDecimal("100")).divide(new BigDecimal(students.size()), 2, BigDecimal.ROUND_HALF_UP);
            studentProgressVo.setFinishProgress(installRate);

        }
        return studentProgressVo;
    }

    @Override
    public void updateOrinsertReceiveH(MultipartFile[] files, String sid, String goodsId, String studentId) {
        Receive receive = new Receive();
        List<Receive> list = this.list(Wrappers.<Receive>lambdaQuery().eq(Receive::getStudentId, studentId).eq(Receive::getGoodsId, goodsId));
        if (!CollectionUtils.isEmpty(list)) {
            throw new CustomException("18", "已经领取");
        }
        if (files != null && files.length > 0) {
            List<String> stringUrls = filesService.getStringUrls(files);
            if (!CollectionUtils.isEmpty(stringUrls)) {
                receive.setFilesUrl(stringUrls == null ? null : org.apache.commons.lang3.StringUtils.join(stringUrls, ","));
            }
        }
        receive.setReceiveStatus(1);
        receive.setStudentId(studentId);
        receive.setGoodsId(goodsId);
        this.save(receive);

    }

    @Override
    public IPage<StudentClassInfoVo> queryStudentGoods(Integer pageNum, Integer pageSize, String collegeId, String majorId, String className, String studentName, String studentId) {
        List<StudentClassInfoVo> studentClassInfoVos = studentService.getStudentClassInfoVos(collegeId, majorId, className, studentName, null, "1", studentId);
        List<StudentClassInfoVo> classInfoVos = studentClassInfoVos.stream().filter((StudentClassInfoVo s) -> !org.apache.commons.lang3.StringUtils.isEmpty(s.getStudentId())).collect(Collectors.toList());
        List<Goods> goodsList = goodsService.list();
        List<StudentClassInfoVo> studentClassInfoVoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(goodsList)) {
            for (StudentClassInfoVo vo : classInfoVos) {
                List<Receive> receiveList = this.list(Wrappers.<Receive>lambdaQuery().eq(Receive::getReceiveStatus, 1).eq(Receive::getStudentId, vo.getStudentId()));
                if (receiveList.size() != goodsList.size()) {
                    studentClassInfoVoList.add(vo);
                }
            }
        }
        return PageUtils.getPage(studentClassInfoVoList, pageNum, pageSize);
    }
}
